package shark.scheduler.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import shark.scheduler.SchedulerExecutor;
import shark.scheduler.handler.SharkSchedulerConfigure;
import shark.scheduler.model.SharkScheduler;
import shark.scheduler.spi.entity.ScheduledCron;
import shark.scheduler.spi.mapper.ScheduledCronMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Component
public class SchedulerExecutorImpl implements SchedulerExecutor {

    @Autowired
    SharkSchedulerConfigure configure;

    @Autowired
    ScheduledCronMapper cronMapper;

    @Autowired
    ApplicationContext context;

    @Override
    public void startTask(String taskKey) throws ClassNotFoundException {
        Assert.hasText(taskKey, "手动开始任务，任务名taskKey不能为空！");
        cronMapper.updateStatusByCronKey(taskKey, 1);
    }

    @Override
    public void startOnceTask(String taskKey) throws ClassNotFoundException {
        Assert.hasText(taskKey, "手动执行一次任务，任务名taskKey不能为空！");
        ScheduledCron scheduledCron = cronMapper.findByKey(taskKey);
        Class<?> clazz = Class.forName(scheduledCron.getTaskKey());
        SharkScheduler task = (SharkScheduler) context.getBean(clazz);
        task.execute();
    }

    @Override
    public void addTask(ScheduledCron scheduledCron) throws ClassNotFoundException {
        Assert.hasText(scheduledCron.getTaskKey(), "新增任务，任务所在类名taskKey不能为空！");
        Assert.hasText(scheduledCron.getCronExpression(), "新增任务，任务cron表达式不能为空！");

        scheduledCron.setTaskId(UUID.randomUUID().toString().replaceAll("-",""));
        scheduledCron.setStatus(1);
        Class<?> clazz = Class.forName(scheduledCron.getTaskKey());
        Object task = context.getBean(clazz);
        configure.addTriggerTask(scheduledCron.getTaskKey(),
                new TriggerTask((Runnable) task, new CronTrigger(scheduledCron.getCronExpression())));
        cronMapper.addScheduledCron(scheduledCron);
    }

    @Override
    public void cancelTask(String taskKey) {
        Assert.hasText(taskKey, "取消任务，任务所在类名taskKey不能为空！");
        configure.cancelTriggerTask(taskKey);
    }

    @Override
    public void pauseTask(String taskKey) {
        Assert.hasText(taskKey, "暂停任务，任务所在类名taskKey不能为空！");
        cronMapper.updateStatusByCronKey(taskKey, 2);
    }

    @Override
    public List<ScheduledCron> scanTask() {
        Map<String, SharkScheduler> map = context.getBeansOfType(SharkScheduler.class);
        List<ScheduledCron> list = new ArrayList<>(map.size());
        map.forEach((key, value) -> {
            ScheduledCron cron = new ScheduledCron();
            String taskKey = value.getClass().getName();
            ScheduledCron scheduledCron = cronMapper.findByKey(taskKey);
            if (scheduledCron != null) {
                cron.setTaskKey(taskKey);
                list.add(cron);
            }
        });
        return list;
    }
}
